🦆 DuckDetector: A Project for Automatically Detecting Ducks 🦆¶
This notebook covers training the YOLOv8 Object Detection Models which will be deployed on various user interfaces.
Author: Timothy Do
Setup¶
This section checks the adequate preqrequisites are installed in the Python environment and also install additional dependencies depending if the user is running Google CoLab or not. Before you begin, make sure to have the following external prerequisites installed:
- ffmpeg
# Check if Environment is in Google CoLab:
IN_COLAB = True
try:
import google.colab
except:
IN_COLAB = False
if(IN_COLAB):
!curl https://raw.githubusercontent.com/dotimothy/DuckDetector/model/requirements.txt -o ./requirements.txt
!apt install ffmpeg
!pip install -r requirements.txt
Requirement already satisfied: gitpython>=3.1.30 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 5)) (3.1.41) Requirement already satisfied: matplotlib>=3.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 6)) (3.8.2) Requirement already satisfied: numpy>=1.23.5 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 7)) (1.26.4) Requirement already satisfied: opencv-python>=4.1.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 8)) (4.9.0.80) Requirement already satisfied: Pillow>=10.0.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 9)) (10.2.0) Requirement already satisfied: psutil in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 10)) (5.9.8) Requirement already satisfied: PyYAML>=5.3.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 11)) (6.0.1) Requirement already satisfied: requests>=2.23.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 12)) (2.32.3) Requirement already satisfied: scipy>=1.4.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 13)) (1.12.0) Requirement already satisfied: thop>=0.1.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 14)) (0.1.1.post2209072238) Requirement already satisfied: torch>=1.8.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 15)) (2.1.2+cu121) Requirement already satisfied: torchvision>=0.9.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 16)) (0.16.2+cu121) Requirement already satisfied: tqdm>=4.64.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 17)) (4.66.1) Requirement already satisfied: ultralytics>=8.0.232 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 18)) (8.1.6) Requirement already satisfied: pandas>=1.1.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 27)) (2.2.0) Requirement already satisfied: seaborn>=0.11.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 28)) (0.13.2) Requirement already satisfied: setuptools>=65.5.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 42)) (69.0.3) Requirement already satisfied: GPUtil in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 53)) (1.4.0) Requirement already satisfied: py-cpuinfo in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 54)) (9.0.0) Requirement already satisfied: openimages in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 57)) (0.0.1) Requirement already satisfied: label-studio in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from -r requirements.txt (line 58)) (1.13.0) Requirement already satisfied: gitdb<5,>=4.0.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from gitpython>=3.1.30->-r requirements.txt (line 5)) (4.0.11) Requirement already satisfied: contourpy>=1.0.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (1.2.0) Requirement already satisfied: cycler>=0.10 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (0.12.1) Requirement already satisfied: fonttools>=4.22.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (4.47.2) Requirement already satisfied: kiwisolver>=1.3.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (1.4.5) Requirement already satisfied: packaging>=20.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (23.2) Requirement already satisfied: pyparsing>=2.3.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (3.1.1) Requirement already satisfied: python-dateutil>=2.7 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from matplotlib>=3.3->-r requirements.txt (line 6)) (2.8.2) Requirement already satisfied: charset-normalizer<4,>=2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (2.1.1) Requirement already satisfied: idna<4,>=2.5 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (3.4) Requirement already satisfied: urllib3<3,>=1.21.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (1.26.19) Requirement already satisfied: certifi>=2017.4.17 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from requests>=2.23.0->-r requirements.txt (line 12)) (2022.12.7) Requirement already satisfied: filelock in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (3.9.0) Requirement already satisfied: typing-extensions in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (4.12.2) Requirement already satisfied: sympy in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (1.12) Requirement already satisfied: networkx in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (2.8.8) Requirement already satisfied: jinja2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (3.1.2) Requirement already satisfied: fsspec in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from torch>=1.8.0->-r requirements.txt (line 15)) (2024.3.1) Requirement already satisfied: colorama in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from tqdm>=4.64.0->-r requirements.txt (line 17)) (0.4.6) Requirement already satisfied: pytz>=2020.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from pandas>=1.1.4->-r requirements.txt (line 27)) (2022.7.1) Requirement already satisfied: tzdata>=2022.7 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from pandas>=1.1.4->-r requirements.txt (line 27)) (2023.4) Requirement already satisfied: boto3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openimages->-r requirements.txt (line 57)) (1.34.156) Requirement already satisfied: cvdata in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openimages->-r requirements.txt (line 57)) (0.0.3) Requirement already satisfied: lxml in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openimages->-r requirements.txt (line 57)) (5.2.2) Requirement already satisfied: Django<3.3.0,>=3.2.24 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.2.25) Requirement already satisfied: appdirs>=1.4.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.4.4) Requirement already satisfied: attr==0.3.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.3.1) Requirement already satisfied: attrs>=19.2.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (23.2.0) Requirement already satisfied: azure-storage-blob>=12.6.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (12.22.0) Requirement already satisfied: bleach<5.1.0,>=5.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (5.0.1) Requirement already satisfied: boto<3.0.0,>=2.49.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.49.0) Requirement already satisfied: botocore<2.0.0,>=1.31.58 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.34.156) Requirement already satisfied: boxing>=0.1.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.1.4) Requirement already satisfied: defusedxml>=0.7.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.7.1) Requirement already satisfied: django-annoying==0.10.6 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.10.6) Requirement already satisfied: django-cors-headers==3.6.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.6.0) Requirement already satisfied: django-csp==3.7 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.7) Requirement already satisfied: django-debug-toolbar==3.2.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.2.1) Requirement already satisfied: django-environ==0.10.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.10.0) Requirement already satisfied: django-extensions==3.1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.1.0) Requirement already satisfied: django-filter==2.4.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.4.0) Requirement already satisfied: django-model-utils==4.1.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (4.1.1) Requirement already satisfied: django-ranged-fileresponse>=0.1.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.1.2) Requirement already satisfied: django-rq==2.5.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.5.1) Requirement already satisfied: django-storages==1.12.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.12.3) Requirement already satisfied: django-user-agents==0.4.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.4.0) Requirement already satisfied: djangorestframework==3.13.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.13.1) Requirement already satisfied: drf-dynamic-fields==0.3.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.3.0) Requirement already satisfied: drf-flex-fields==0.9.5 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.9.5) Requirement already satisfied: drf-generators==0.3.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.3.0) Requirement already satisfied: google-cloud-logging<4.0.0,>=3.10.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.11.1) Requirement already satisfied: google-cloud-storage<3.0.0,>=2.13.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.18.1) Requirement already satisfied: htmlmin==0.1.12 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.1.12) Requirement already satisfied: humansignal-drf-yasg>=1.21.9 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.21.9) Requirement already satisfied: jsonschema==3.2.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.2.0) Requirement already satisfied: label-studio-sdk==1.0.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.0.4) Requirement already satisfied: launchdarkly-server-sdk==8.2.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (8.2.1) Requirement already satisfied: lockfile>=0.12.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.12.2) Requirement already satisfied: openai<2.0.0,>=1.10.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.40.1) Requirement already satisfied: ordered-set==4.0.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (4.0.2) Requirement already satisfied: psycopg2-binary==2.9.9 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.9.9) Requirement already satisfied: pydantic>=2.7.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.8.2) Requirement already satisfied: python-json-logger==2.0.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.0.4) Requirement already satisfied: redis<4.0,>=3.5 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (3.5.3) Requirement already satisfied: rq==1.10.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (1.10.1) Requirement already satisfied: rules==2.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.2) Requirement already satisfied: sentry-sdk>=1.1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (2.1.1) Requirement already satisfied: ujson>=3.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (5.9.0) Requirement already satisfied: wheel<=0.40.0,>=0.38.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.40.0) Requirement already satisfied: xmljson==0.2.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio->-r requirements.txt (line 58)) (0.2.1) Requirement already satisfied: six in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from django-annoying==0.10.6->label-studio->-r requirements.txt (line 58)) (1.16.0) Requirement already satisfied: sqlparse>=0.2.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from django-debug-toolbar==3.2.1->label-studio->-r requirements.txt (line 58)) (0.5.1) Requirement already satisfied: user-agents in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from django-user-agents==0.4.0->label-studio->-r requirements.txt (line 58)) (2.2.0) Requirement already satisfied: pyrsistent>=0.14.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from jsonschema==3.2.0->label-studio->-r requirements.txt (line 58)) (0.20.0) Requirement already satisfied: httpx>=0.21.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (0.27.0) Requirement already satisfied: ijson>=3.2.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (3.3.0) Requirement already satisfied: nltk==3.6.7 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (3.6.7) Requirement already satisfied: requests-mock==1.12.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (1.12.1) Requirement already satisfied: expiringdict>=1.1.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from launchdarkly-server-sdk==8.2.1->label-studio->-r requirements.txt (line 58)) (1.2.2) Requirement already satisfied: pyRFC3339>=1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from launchdarkly-server-sdk==8.2.1->label-studio->-r requirements.txt (line 58)) (1.1) Requirement already satisfied: semver>=2.10.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from launchdarkly-server-sdk==8.2.1->label-studio->-r requirements.txt (line 58)) (3.0.2) Requirement already satisfied: click>=5.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from rq==1.10.1->label-studio->-r requirements.txt (line 58)) (8.1.7) Requirement already satisfied: joblib in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from nltk==3.6.7->label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (1.3.2) Requirement already satisfied: regex>=2021.8.3 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from nltk==3.6.7->label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (2023.12.25) Requirement already satisfied: azure-core>=1.28.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from azure-storage-blob>=12.6.0->label-studio->-r requirements.txt (line 58)) (1.30.2) Requirement already satisfied: cryptography>=2.1.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from azure-storage-blob>=12.6.0->label-studio->-r requirements.txt (line 58)) (43.0.0) Requirement already satisfied: isodate>=0.6.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from azure-storage-blob>=12.6.0->label-studio->-r requirements.txt (line 58)) (0.6.1) Requirement already satisfied: webencodings in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from bleach<5.1.0,>=5.0.0->label-studio->-r requirements.txt (line 58)) (0.5.1) Requirement already satisfied: jmespath<2.0.0,>=0.7.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from boto3->openimages->-r requirements.txt (line 57)) (1.0.1) Requirement already satisfied: s3transfer<0.11.0,>=0.10.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from boto3->openimages->-r requirements.txt (line 57)) (0.10.2) Requirement already satisfied: asgiref<4,>=3.3.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from Django<3.3.0,>=3.2.24->label-studio->-r requirements.txt (line 58)) (3.8.1) Requirement already satisfied: smmap<6,>=3.0.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from gitdb<5,>=4.0.1->gitpython>=3.1.30->-r requirements.txt (line 5)) (5.0.1) Requirement already satisfied: google-api-core!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (2.19.1) Requirement already satisfied: google-auth!=2.24.0,!=2.25.0,<3.0.0dev,>=2.14.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (2.28.1) Requirement already satisfied: google-cloud-appengine-logging<2.0.0dev,>=0.1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.4.5) Requirement already satisfied: google-cloud-audit-log<1.0.0dev,>=0.1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (0.2.5) Requirement already satisfied: google-cloud-core<3.0.0dev,>=2.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (2.4.1) Requirement already satisfied: grpc-google-iam-v1<1.0.0dev,>=0.12.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (0.13.1) Requirement already satisfied: opentelemetry-api>=1.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.26.0) Requirement already satisfied: proto-plus<2.0.0dev,>=1.22.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.24.0) Requirement already satisfied: protobuf!=4.21.0,!=4.21.1,!=4.21.2,!=4.21.3,!=4.21.4,!=4.21.5,<6.0.0dev,>=3.20.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (4.25.3) Requirement already satisfied: google-resumable-media>=2.6.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-storage<3.0.0,>=2.13.0->label-studio->-r requirements.txt (line 58)) (2.7.2) Requirement already satisfied: google-crc32c<2.0dev,>=1.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-cloud-storage<3.0.0,>=2.13.0->label-studio->-r requirements.txt (line 58)) (1.5.0) Requirement already satisfied: inflection>=0.3.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from humansignal-drf-yasg>=1.21.9->label-studio->-r requirements.txt (line 58)) (0.5.1) Requirement already satisfied: uritemplate>=3.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from humansignal-drf-yasg>=1.21.9->label-studio->-r requirements.txt (line 58)) (4.1.1) Requirement already satisfied: anyio<5,>=3.5.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openai<2.0.0,>=1.10.0->label-studio->-r requirements.txt (line 58)) (4.2.0) Requirement already satisfied: distro<2,>=1.7.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openai<2.0.0,>=1.10.0->label-studio->-r requirements.txt (line 58)) (1.9.0) Requirement already satisfied: jiter<1,>=0.4.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openai<2.0.0,>=1.10.0->label-studio->-r requirements.txt (line 58)) (0.5.0) Requirement already satisfied: sniffio in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from openai<2.0.0,>=1.10.0->label-studio->-r requirements.txt (line 58)) (1.3.0) Requirement already satisfied: annotated-types>=0.4.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from pydantic>=2.7.3->label-studio->-r requirements.txt (line 58)) (0.7.0) Requirement already satisfied: pydantic-core==2.20.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from pydantic>=2.7.3->label-studio->-r requirements.txt (line 58)) (2.20.1) Requirement already satisfied: MarkupSafe>=2.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from jinja2->torch>=1.8.0->-r requirements.txt (line 15)) (2.1.3) Requirement already satisfied: mpmath>=0.19 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from sympy->torch>=1.8.0->-r requirements.txt (line 15)) (1.3.0) Requirement already satisfied: cffi>=1.12 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from cryptography>=2.1.4->azure-storage-blob>=12.6.0->label-studio->-r requirements.txt (line 58)) (1.16.0) Requirement already satisfied: googleapis-common-protos<2.0.dev0,>=1.56.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-api-core!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.63.2) Requirement already satisfied: grpcio<2.0dev,>=1.33.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.65.4) Requirement already satisfied: grpcio-status<2.0.dev0,>=1.33.2 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-api-core[grpc]!=2.0.*,!=2.1.*,!=2.10.*,!=2.2.*,!=2.3.*,!=2.4.*,!=2.5.*,!=2.6.*,!=2.7.*,!=2.8.*,!=2.9.*,<3.0.0dev,>=1.34.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.62.3) Requirement already satisfied: cachetools<6.0,>=2.0.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-auth!=2.24.0,!=2.25.0,<3.0.0dev,>=2.14.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (5.3.3) Requirement already satisfied: pyasn1-modules>=0.2.1 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-auth!=2.24.0,!=2.25.0,<3.0.0dev,>=2.14.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (0.3.0) Requirement already satisfied: rsa<5,>=3.1.4 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from google-auth!=2.24.0,!=2.25.0,<3.0.0dev,>=2.14.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (4.9) Requirement already satisfied: httpcore==1.* in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from httpx>=0.21.2->label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (1.0.5) Requirement already satisfied: h11<0.15,>=0.13 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from httpcore==1.*->httpx>=0.21.2->label-studio-sdk==1.0.4->label-studio->-r requirements.txt (line 58)) (0.14.0) Requirement already satisfied: deprecated>=1.2.6 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from opentelemetry-api>=1.0.0->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.2.14) Requirement already satisfied: importlib-metadata<=8.0.0,>=6.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from opentelemetry-api>=1.0.0->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (7.1.0) Requirement already satisfied: ua-parser>=0.10.0 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from user-agents->django-user-agents==0.4.0->label-studio->-r requirements.txt (line 58)) (0.18.0) Requirement already satisfied: pycparser in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from cffi>=1.12->cryptography>=2.1.4->azure-storage-blob>=12.6.0->label-studio->-r requirements.txt (line 58)) (2.22) Requirement already satisfied: wrapt<2,>=1.10 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from deprecated>=1.2.6->opentelemetry-api>=1.0.0->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (1.14.1) Requirement already satisfied: zipp>=0.5 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from importlib-metadata<=8.0.0,>=6.0->opentelemetry-api>=1.0.0->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (3.18.1) Requirement already satisfied: pyasn1<0.6.0,>=0.4.6 in c:\users\timothy do\appdata\local\programs\python\python311\lib\site-packages (from pyasn1-modules>=0.2.1->google-auth!=2.24.0,!=2.25.0,<3.0.0dev,>=2.14.1->google-cloud-logging<4.0.0,>=3.10.0->label-studio->-r requirements.txt (line 58)) (0.5.1)
[notice] A new release of pip is available: 24.0 -> 24.2 [notice] To update, run: python.exe -m pip install --upgrade pip
# Importing Libraries
import os
import sys
import torch
import cv2 as cv
import numpy as np
import cpuinfo
import psutil
import ultralytics
import pandas as pd
from tqdm import tqdm
import random
from openimages.download import download_dataset
import matplotlib.pyplot as plt
import re
import shutil
from IPython.display import Video
# For Printing Purposes
class color:
PURPLE = '\033[95m'
CYAN = '\033[96m'
DARKCYAN = '\033[36m'
BLUE = '\033[94m'
GREEN = '\033[92m'
YELLOW = '\033[93m'
RED = '\033[91m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
END = '\033[0m'
To adequately train the DuckDetector, make sure a GPU is detected in the runtime. GPU accelerates the developnment of AI models by parallelizing matrix multiplication and convolution operations that are nececssary to accelerate gradient backpropogation for effcient learning.
# Environment Specifications
print(f'{color.BOLD}***** Environment Specifications *****{color.END}')
print(f"{color.BOLD}In CoLab{color.END}: {IN_COLAB}")
# Device to Develop PyTorch Models On
use_cuda = torch.cuda.is_available()
use_mps = torch.backends.mps.is_available()
device = torch.device('cuda' if use_cuda else ('mps' if use_mps else 'cpu'))
print(f'{color.BOLD}Torch Device:{color.END} {device}')
platformToOS = {'darwin': 'MacOS', 'win32': 'Windows', 'linux2': 'Linux', 'linux': 'Linux'}
print(f'{color.BOLD}OS:{color.END} {platformToOS[sys.platform]}')
print(f'{color.BOLD}CPU:{color.END} {cpuinfo.get_cpu_info()["brand_raw"]}')
print(f'\t- {color.BOLD}# CPU Cores:{color.END} {psutil.cpu_count(logical=False)}')
print(f'\t- {color.BOLD}# CPU Threads:{color.END} {psutil.cpu_count(logical=True)}')
print(f'\t- {color.BOLD}Total System RAM:{color.END} {psutil.virtual_memory().total/(1024**3):.1f} GB ')
print(f'\n{color.BOLD}GPU:{color.END} {torch.cuda.get_device_name(device) if use_cuda else "MPS" if use_mps else None}')
if(use_cuda):
print(f'\t- {color.BOLD}Total GPU VRAM:{color.END} {torch.cuda.get_device_properties(device).total_memory/(1024**3):.1f} GB\n')
!nvidia-smi
***** Environment Specifications ***** In CoLab: False Torch Device: cuda OS: Windows CPU: 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz - # CPU Cores: 8 - # CPU Threads: 16 - Total System RAM: 127.8 GB GPU: NVIDIA GeForce RTX 3090 - Total GPU VRAM: 24.0 GB Thu Aug 8 12:52:51 2024 +---------------------------------------------------------------------------------------+ | NVIDIA-SMI 536.67 Driver Version: 536.67 CUDA Version: 12.2 | |-----------------------------------------+----------------------+----------------------+ | GPU Name TCC/WDDM | Bus-Id Disp.A | Volatile Uncorr. ECC | | Fan Temp Perf Pwr:Usage/Cap | Memory-Usage | GPU-Util Compute M. | | | | MIG M. | |=========================================+======================+======================| | 0 NVIDIA GeForce RTX 3090 WDDM | 00000000:01:00.0 On | N/A | | 0% 42C P8 37W / 350W | 1204MiB / 24576MiB | 33% Default | | | | N/A | +-----------------------------------------+----------------------+----------------------+ +---------------------------------------------------------------------------------------+ | Processes: | | GPU GI CI PID Type Process name GPU Memory | | ID ID Usage | |=======================================================================================| | 0 N/A N/A 920 C+G ...__8wekyb3d8bbwe\WindowsTerminal.exe N/A | | 0 N/A N/A 1256 C+G ...oogle\Chrome\Application\chrome.exe N/A | | 0 N/A N/A 3916 C+G ...Programs\Microsoft VS Code\Code.exe N/A | | 0 N/A N/A 8852 C+G ...5n1h2txyewy\ShellExperienceHost.exe N/A | | 0 N/A N/A 8904 C+G C:\Windows\explorer.exe N/A | | 0 N/A N/A 9244 C+G C:\Program Files\Parsec\parsecd.exe N/A | | 0 N/A N/A 10512 C+G ...nt.CBS_cw5n1h2txyewy\SearchHost.exe N/A | | 0 N/A N/A 10564 C+G ...2txyewy\StartMenuExperienceHost.exe N/A | | 0 N/A N/A 11292 C+G ...GeForce Experience\NVIDIA Share.exe N/A | | 0 N/A N/A 12968 C+G ...t.LockApp_cw5n1h2txyewy\LockApp.exe N/A | | 0 N/A N/A 13592 C+G ...n\126.0.2592.113\msedgewebview2.exe N/A | | 0 N/A N/A 14136 C+G ...\cef\cef.win7x64\steamwebhelper.exe N/A | | 0 N/A N/A 14404 C+G ...ekyb3d8bbwe\PhoneExperienceHost.exe N/A | | 0 N/A N/A 15520 C+G ...GeForce Experience\NVIDIA Share.exe N/A | | 0 N/A N/A 16196 C+G ...US\ArmouryDevice\asus_framework.exe N/A | | 0 N/A N/A 16296 C+G ...CBS_cw5n1h2txyewy\TextInputHost.exe N/A | | 0 N/A N/A 18572 C+G ...\cef\cef.win7x64\steamwebhelper.exe N/A | | 0 N/A N/A 18696 C+G ...inaries\Win64\EpicGamesLauncher.exe N/A | | 0 N/A N/A 19100 C+G ...ne\Binaries\Win64\EpicWebHelper.exe N/A | +---------------------------------------------------------------------------------------+
Dataset Preprocessing¶
This section covers how to download various datasets and unify them under a common standard for training the duck detection models. The spreadsheet of each individual dataset viewable in the cell below:
dataset_df = pd.read_csv('https://docs.google.com/spreadsheets/d/1AfuZ8lFaX3Iy5eNDXTxvasOeE4mqal2Pe8c--oDRmOg/export?format=csv')
display(dataset_df)
| Name | # of Images | Original Source | ImagesCV | Include Cartoon | Link | |
|---|---|---|---|---|---|---|
| 0 | OpenImages (Duck) | 1289 | Open Images Dataset V7 | No | No | https://storage.googleapis.com/openimages/web/... |
| 1 | OpenImages (Goose) | 577 | Open Images Dataset V7 | No | No | https://storage.googleapis.com/openimages/web/... |
| 2 | Wood Duck | 216 | 300 Bird Species Classification | Yes | No | https://images.cv/dataset/wood-duck-image-clas... |
| 3 | Teal Duck | 167 | 300 Bird Species Classifcation | Yes | No | https://images.cv/dataset/teal-duck-image-clas... |
| 4 | Steamer Duck | 122 | 300 Bird Species Classification | Yes | No | https://images.cv/dataset/steamer-duck-image-c... |
| 5 | Red Headed Duck | 127 | 300 Bird Species Classification | Yes | No | https://images.cv/dataset/red-headed-duck-imag... |
| 6 | Mandrin Duck | 134 | 300 Bird Species Classification | Yes | No | https://images.cv/dataset/mandrin-duck-image-c... |
| 7 | Mallard Duck | 140 | 300 Bird Species Classification | Yes | No | https://images.cv/dataset/mallard-duck-image-c... |
| 8 | Duck | 1000 | Domainnet | Yes | Yes | https://images.cv/dataset/duck-image-classific... |
| 9 | Drake | 1300 | Imagenet Object Localization | Yes | No | https://images.cv/dataset/drake-image-classifi... |
OpenImages¶
This section will overview Google's already annotated image sets for the Duck and the Goose from their Openimages dataset. Each subset has the following amount of images:
Duck
- Train: 1151 Images
- Validation: 37 Images
- Test: 101 Images
- Total: 1289 Images
Goose
- Train: 518 Images
- Validation: 16 Images
- Test: 43 Images
- Total: 577 Images
It is to be noted that the openimages API merges the train/val/test subsets all into a single collection (i.e., all images are merged into a single folder, anonymizing which subset each one was in).
# Downloading the OpenImages Subset of Duck and Goose
dataPath = './data/'
openPath = f'{dataPath}/OpenImages/'
duckPath = f'{openPath}/duck/'
goosePath = f'{openPath}/goose/'
if(not(os.path.exists(dataPath))): os.mkdir(dataPath) # Making Data Directory
if(not(os.path.exists(openPath))): os.mkdir(openPath) # Making OpenImages Directory
if(not(os.path.exists(duckPath))): # Downloading Duck Subset
print(f'***** Downloading {color.BOLD}OpenImages Duck{color.END} Dataset!*****')
download_dataset(openPath,['Duck',],annotation_format='darknet')
if(not(os.path.exists(goosePath))): # Downloading Duck Subset
print(f'\n***** Downloading {color.BOLD}OpenImages Goose{color.END} Dataset! *****')
download_dataset(openPath,['Goose',],annotation_format='darknet')
Now that Duck and Goose sets from OpenImages have been downloaded, let's visualize a few of the duck images and their corresponding bounding box coordinates created by humans! The format of the each YOLO bounding box coordinate label is as the following:
class x_center y_center width height
where the center coordinates (i.e., the upper left of the box), width, and height are normalized from 0 to 1. For initial visualization, bounding boxes are drawn onto a random image on the Duck set.
# Helper Function to Draw Bounding Boxes
def drawBoundingBox(image,label): # Assume a Single Object Class
h,w,c = image.shape
xNorm,yNorm,bw,bh = [float(res) for res in re.findall("\d+\.\d+",label)]
image = cv.rectangle(image,(int(w*(xNorm-0.5*bw)),int(h*(yNorm-0.5*bh))),(int(w*(xNorm+0.5*bw)),int(h*(yNorm+0.5*bh))),(255,0,0),3)
return image
# Reading an Example Image from Duck Set
img_prefixes = [os.path.split(img)[1].split('.')[0] for img in os.listdir(f'{duckPath}/images/')]
img_prefix = random.choice(img_prefixes)
test_img = plt.imread(f'{duckPath}/images/{img_prefix}.jpg')
print(f'{color.BOLD}Test Duck Image{color.END}')
plt.figure()
plt.imshow(test_img)
plt.title(f'Test Duck {img_prefix}')
plt.show()
# Reading Bounding Box Labels for the Example Duck Image
print(f'{color.BOLD}Test Duck ({img_prefix}) Image Labels{color.END}')
test_labels = open(f'{duckPath}/darknet/{img_prefix}.txt',newline='')
for label in test_labels.readlines():
print(label,end='')
test_labels.close()
Test Duck Image
Test Duck (46130ade60933577) Image Labels
0 0.415625 0.548266 0.48750000000000004 0.680412
0 0.415625 0.548266 0.48750000000000004 0.680412
Let's make sense of the bounding box labels and visualize them by drawing the manually annotated bounding boxes to the image!
# Reading Test Duck Labels
test_label = open(f'{duckPath}/darknet/{img_prefix}.txt',newline='')
test_img_bounded = test_img.copy()
for label in test_label.readlines():
test_img_bounded = drawBoundingBox(test_img_bounded,label)
# Displaying Bounded Box over the Duck Image
print(f'{color.BOLD}Test Duck {img_prefix} with Bounded Box Label{color.END}')
plt.figure()
plt.imshow(test_img_bounded)
plt.title(f'Test Duck {img_prefix} with Bounded Box')
plt.show()
Test Duck 46130ade60933577 with Bounded Box Label
Let's try the same bounding box visualization on the Goose subset.
# Reading an Example Image from Goose Set
img_prefixes = [os.path.split(img)[1].split('.')[0] for img in os.listdir(f'{goosePath}/images/')]
img_prefix = random.choice(img_prefixes)
test_img = plt.imread(f'{goosePath}/images/{img_prefix}.jpg')
print(f'{color.BOLD}Test Goose Image{color.END}')
plt.figure()
plt.imshow(test_img)
plt.title(f'Test Goose {img_prefix}')
plt.show()
# Reading Bounding Box Labels for the Example Goose Image
print(f'{color.BOLD}Test Goose ({img_prefix}) Image Labels{color.END}')
test_labels = open(f'{goosePath}/darknet/{img_prefix}.txt',newline='')
test_img_bounded = test_img.copy()
for label in test_labels.readlines():
test_img_bounded = drawBoundingBox(test_img_bounded,label)
print(label,end='')
test_labels.close()
# Displaying Bounded Box over the Goose Image
print(f'\n{color.BOLD}Test Goose {img_prefix} with Bounded Box Label{color.END}')
plt.figure()
plt.imshow(test_img_bounded)
plt.title(f'Test Goose {img_prefix} with Bounded Box')
plt.show()
Test Goose Image
Test Goose (3ae726ecfaac7c77) Image Labels 0 0.34374999999999994 0.5012005 0.5137499999999999 0.5414169999999999 Test Goose 3ae726ecfaac7c77 with Bounded Box Label
Splitting Openimages Set into Train/Test/Val Subsets¶
For YOLOv8, the dataset needs to be split into training (train), validation (val), and testing (test) subsets to train the object detection model properly. The original Openimage subset structure for the Duck/Goose is as follows:
duck/
darknet/
001.txt
002.txt
...
images/
001.jpg
002.jpg
...
After conversion, the dataset should have a structure similar to below:
duck_train/
classes.txt
config.yaml
images/
train/
001.txt
002.txt
...
val/
003.txt
004.txt
...
test/
005.txt
006.txt
...
images/
train/
001.jpg
002.jpg
...
val/
003.jpg
004.jpg
...
test/
005.jpg
006.jpg
...
where classes.txt contains the name of the classes (i.e., Duck), and config.yaml contains the training configuration such as number of classes, location of train/val subsets, and class names. Below will define functions on converting the OpenImage datasets.
# Split an Openimage Set into Train/Val/Test Subsets
def splitOpenImages(ogPath,split=[0.9,0.05,0.05],seed=None):
# Created Necessary Directories
newPath = f'{os.path.dirname(ogPath)}_train'
newImgPath = f'{newPath}/images'
newLabelPath = f'{newPath}/labels'
subsets = ['train','val','test']
if(not(os.path.exists(newPath))): os.mkdir(newPath)
if(not(os.path.exists(newImgPath))): os.mkdir(newImgPath)
if(not(os.path.exists(newLabelPath))): os.mkdir(newLabelPath)
# Create Train/Val/Test Subdirectories
for mainDir in [newImgPath,newLabelPath]:
for subset in subsets:
subPath = f'{mainDir}/{subset}'
if(not(os.path.exists(subPath))): os.mkdir(subPath)
# Creating Dataset Config Files
createClassFile(newPath)
createYAMLConfig(newPath)
# Getting Image Prefixes (Assuming 1-1 Correspondence between Images and Labels) & Shuffle Them
prefixes = [os.path.split(img)[1].split('.')[0] for img in os.listdir(f'{ogPath}/images/')]
N = len(prefixes)
if(seed is not None): random.seed(seed) # Set random seed if manually entered
random.shuffle(prefixes)
j = 0
for i,prefix in enumerate(prefixes):
if j < len(subsets):
if i < int(sum(split[:j+1])*N):
shutil.copy2(f'{ogPath}/images/{prefix}.jpg',f'{newImgPath}/{subsets[j]}/{prefix}.jpg') # Copying Image
shutil.copy2(f'{ogPath}/darknet/{prefix}.txt',f'{newLabelPath}/{subsets[j]}/{prefix}.txt') # Copying Label
else: # Go on to Next Subset
j += 1
# Create a YAML Config for the Dataset
def createYAMLConfig(dataPath):
yamlPath = f'{dataPath}/config.yaml'
yamlFile = open(yamlPath,'w',newline='')
yamlFile.write(f'# DuckDetector config.yaml for {dataPath.split("/")[-1]}\n\n')
yamlFile.write(f'# Data + Train/Val/Test Subset Paths\n')
cwd = os.getcwd().replace("\\","//")
yamlFile.write(f'path: {cwd}/{dataPath}\n')
yamlFile.write('train: images/train\n')
yamlFile.write('val: images/val\n')
yamlFile.write('test: images/test\n\n')
yamlFile.write(f'# Class Names\n')
yamlFile.write('nc: 1\n')
yamlFile.write('names:\n 0: Duck')
yamlFile.close()
# Create a Class Name File for the Dataset
def createClassFile(dataPath):
classPath = f'{dataPath}/classes.txt'
classFile = open(classPath,'w',newline='')
classFile.write('Duck')
classFile.close()
# Spltting Open Images on Ducks (Set Manual Seed for Reproducible Results)
splitOpenImages(duckPath,seed=42)
# Spltting Open Images on Goose (Set Manual Seed for Reproducible Results)
splitOpenImages(goosePath,seed=42)
Train an Initial Object Detection Model with YOLOv8¶
This section covers how to train an initial YOLOv8 model with the Openimages Duck/Goose Dataset.
# Smallest Base Pretrained Model
modelDir = './models'
modelPath = f'{modelDir}/OpenImageDuck_YOLOv8n.pt'
preTrained = True
if(not(os.path.exists(modelDir))): os.mkdir(modelDir)
if(not(preTrained)):
model = ultralytics.YOLO('yolov8n.pt').to(device)
# Train Model
model.train(data='data/OpenImages/duck_train/config.yaml',epochs=25,batch=64,imgsz=640,verbose=True)
# Final YOLOv8 Metrics
metrics = model.val()
# Saving Intial Model
model.save(f'{modelPath}')
else:
if(IN_COLAB):
!curl https://raw.githubusercontent.com/dotimothy/DuckDetector/model/models/OpenImageDuck_YOLOv8n.pt -o {modelPath}
model = ultralytics.YOLO(modelPath).to(device)
# Results on the Test Set
results = model(f'data/OpenImages/duck_train/images/test')
image 1/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\008af93d188c0829.jpg: 480x640 1 Duck, 98.2ms image 2/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\02e19ebb9fe4d496.jpg: 448x640 1 Duck, 92.6ms image 3/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\0330e1f32fbe09aa.jpg: 448x640 1 Duck, 8.2ms image 4/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\036e28763582dc33.jpg: 384x640 5 Ducks, 93.2ms image 5/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\03d277285c636493.jpg: 448x640 3 Ducks, 8.0ms image 6/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\05417166b19a0c7b.jpg: 640x576 3 Ducks, 95.6ms image 7/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\05f9e9f5ab81fcd1.jpg: 640x448 9 Ducks, 93.1ms image 8/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\0e752bd12f29a75b.jpg: 480x640 6 Ducks, 7.5ms image 9/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\128d78110f2d1525.jpg: 448x640 5 Ducks, 8.0ms image 10/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\12edd4e1cec4d008.jpg: 480x640 4 Ducks, 7.0ms image 11/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\14e62d96cddf3346.jpg: 480x640 5 Ducks, 7.0ms image 12/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\1726e7e42ad92ec2.jpg: 448x640 4 Ducks, 9.0ms image 13/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\173089b187ae8acb.jpg: 544x640 3 Ducks, 92.5ms image 14/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\18605fb311b4bcec.jpg: 448x640 3 Ducks, 9.0ms image 15/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\1af60feda5a2204f.jpg: 480x640 4 Ducks, 8.0ms image 16/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\1b744e05715d176c.jpg: 448x640 2 Ducks, 8.0ms image 17/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\1f27c304b2638680.jpg: 448x640 (no detections), 7.9ms image 18/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\2513d21df8a9ffc3.jpg: 480x640 1 Duck, 7.0ms image 19/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\2d3cc0c02e510543.jpg: 480x640 7 Ducks, 7.0ms image 20/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\34f6b7fadbe6754d.jpg: 480x640 3 Ducks, 8.0ms image 21/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\362577eaceb4f40e.jpg: 448x640 4 Ducks, 10.0ms image 22/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\43bc239fbbfacefb.jpg: 544x640 2 Ducks, 9.0ms image 23/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\45e23c1e0a8bf052.jpg: 480x640 1 Duck, 9.0ms image 24/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\4a939e84bbb9ad08.jpg: 448x640 3 Ducks, 7.0ms image 25/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\4bda7e5d5d9ac2c5.jpg: 512x640 2 Ducks, 97.0ms image 26/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\4ca1f813c6116c6e.jpg: 640x608 1 Duck, 93.1ms image 27/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\4e408e4efbef1e9b.jpg: 512x640 16 Ducks, 7.9ms image 28/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\4f6feeb1c211489c.jpg: 416x640 1 Duck, 97.9ms image 29/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\52013abbf7f2c373.jpg: 480x640 4 Ducks, 7.0ms image 30/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\59200ee97e15fbe8.jpg: 480x640 2 Ducks, 7.0ms image 31/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\632b53c508bf26fd.jpg: 256x640 2 Ducks, 98.9ms image 32/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\68fedd6a94144ac1.jpg: 448x640 5 Ducks, 8.0ms image 33/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\6991b2087ac2c02e.jpg: 480x640 1 Duck, 7.0ms image 34/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\6f0224f6f2da5ed0.jpg: 224x640 7 Ducks, 91.2ms image 35/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\703f31052229276d.jpg: 512x640 2 Ducks, 8.0ms image 36/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\844dcb77c044e159.jpg: 512x640 1 Duck, 7.0ms image 37/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\8562210e85d68c0d.jpg: 448x640 1 Duck, 9.0ms image 38/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\85f6219c8809543e.jpg: 448x640 1 Duck, 7.0ms image 39/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\8a6dddab0184b724.jpg: 448x640 14 Ducks, 7.0ms image 40/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\8b25a2e261829dcc.jpg: 448x640 1 Duck, 8.0ms image 41/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\92a29bc71975c107.jpg: 480x640 3 Ducks, 8.0ms image 42/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\931ef9223bface40.jpg: 640x640 1 Duck, 8.5ms image 43/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\a3b7af2c20f414da.jpg: 448x640 7 Ducks, 8.0ms image 44/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\a3f5f241eb13a719.jpg: 608x640 1 Duck, 91.6ms image 45/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\a40ed6ba446f636e.jpg: 480x640 28 Ducks, 8.0ms image 46/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\add0ce12f9ee862b.jpg: 448x640 1 Duck, 8.1ms image 47/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\aed0284e6f7f83f5.jpg: 608x640 1 Duck, 7.0ms image 48/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\b02fc0f432967ef4.jpg: 608x640 3 Ducks, 8.0ms image 49/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\c41d3e153eae52b0.jpg: 448x640 3 Ducks, 8.0ms image 50/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\d2d1dae10e3b5f39.jpg: 480x640 1 Duck, 8.1ms image 51/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\d5cf175778b51da7.jpg: 640x640 7 Ducks, 9.0ms image 52/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\d8e41f872b98305e.jpg: 448x640 2 Ducks, 8.0ms image 53/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\dd76dff3dc3a3527.jpg: 448x640 2 Ducks, 8.0ms image 54/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\e42eec5fc20b376f.jpg: 480x640 7 Ducks, 8.5ms image 55/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\ead979f6d0e38bb7.jpg: 512x640 1 Duck, 8.6ms image 56/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\eb455a449b30610b.jpg: 480x640 (no detections), 8.0ms image 57/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\f24d5ddbf51d6237.jpg: 448x640 3 Ducks, 8.0ms image 58/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\f34058dc5b4429da.jpg: 480x640 4 Ducks, 7.5ms image 59/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\f5f46af66bfa275f.jpg: 512x640 5 Ducks, 8.0ms image 60/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\f7191ff45cd3d9f1.jpg: 480x640 6 Ducks, 7.0ms image 61/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\f8b9941bb2acb417.jpg: 448x640 1 Duck, 9.0ms image 62/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\fc512137d4c9e1e0.jpg: 384x640 4 Ducks, 8.0ms image 63/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\fec753899b4f83dc.jpg: 448x640 8 Ducks, 9.0ms image 64/64 c:\Users\Timothy Do\Documents\GitHub\DuckDetector\data\OpenImages\duck_train\images\test\ff210701464e68f8.jpg: 480x640 2 Ducks, 8.0ms Speed: 1.9ms preprocess, 24.2ms inference, 1.8ms postprocess per image at shape (1, 3, 480, 640)
# Results on the Blind Set! (Video Outside of the Dataset)
resDir = './results'
if(not(os.path.exists(resDir))): os.mkdir(resDir)
print('Testing Model on Real World Videos!')
print(f'{color.BOLD}Video 1.{color.END} Fountain')
os.system(f"yolo predict model='./models/OpenImageDuck_YOLOv8n.pt' source='https://timothydo.me/RefreshVideos/media/fountain.mp4' project='./results' name='fountain' device={'cuda' if use_cuda else 'mps' if use_mps else 'cpu'}")
os.remove('./fountain.mp4')
print(f'{color.BOLD}Video 2.{color.END} Feeding Ducks')
os.system(f"yolo predict model='./models/OpenImageDuck_YOLOv8n.pt' source='https://timothydo.me/RefreshVideos/media/duck.mp4' project='./results' name='duck' device={'cuda' if use_cuda else 'mps' if use_mps else 'cpu'}")
os.remove('./duck.mp4')
# Converting
if(sys.platform == 'darwin'): # MacOS
shutil.copy2('./results/duck/duck.mp4','./results/duck.mp4')
shutil.copy2('./results/fountain/fountain.mp4','./results/fountain.mp4')
else: # Non-MacOS
os.system('ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i "./results/duck/duck.avi" -c:v h264_nvenc -b:v 2.5M "./results/duck.mp4"')
os.system('ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i "./results/fountain/fountain.avi" -c:v h264_nvenc -b:v 2.5M "./results/fountain.mp4"')
shutil.rmtree('./results/duck/')
shutil.rmtree('./results/fountain/')
Testing Model on Real World Videos! Video 1. Fountain Video 2. Feeding Ducks
Let's look at the Initial Fruits of Our Work!
print(f'{color.BOLD}Annotated Fountain Video{color.END}')
Video('./results/fountain.mp4',embed=True)
Annotated Fountain Video
print(f'{color.BOLD}Annotated Duck Video{color.END}')
Video('./results/Duck.mp4',embed=True)
Annotated Duck Video